﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TopRelax2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            textBox2.Text = "4";
            textBox3.Text = "4";
            textBox4.Text = "200";
            textBox5.Text = "1e-8";
            
        }

        public double uu(double x, double y)
        {
            return Math.Sin(Math.PI * x * y);
        }
        public double funk(double x, double y)
        {
            return -Math.PI * Math.PI * uu(x, y) * (x * x + y * y);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            int n;
            int.TryParse(textBox2.Text, out n);
            int m;
            int.TryParse(textBox3.Text, out m);
            int maxStep;
            int.TryParse(textBox4.Text, out maxStep);
            double eps;
            double.TryParse(textBox5.Text, out eps);

            //формирование вспомогательных массивов
            double h = 1.0 / (2*n);
            double k = 1.0 / (2*m);
            double[,] u = new double[2 * n + 1, 2 * m + 1];
            double[,] b = new double[2 * n + 1, 2 * m + 1];
            for (int p = 0; p <= 2 * n; p++)
                for (int j = 0; j <= 2 * m; j++)
                    b[p, j] = funk(1 + p * h, 2 + j * k);
            for (int i = 1; i < 2 * n; i++)
                u[i, 0] = uu(1 + i * h, 2);
            for (int i = 1; i < 2 * m; i++)
                u[0, i] = uu(1, 2 + i * k);
            for (int i = 1; i < n; i++)
                u[i, 2 * m] = uu(1 + i * h, 3);
            for (int i = n; i < 2 * m; i++)
                u[i, m] = uu(1 + i * h, 2.5);
            for (int i = 1; i < m; i++)
                u[2 * n, i] = uu(2, 2 + i * k);
            for (int i = m + 1; i < 2 * m; i++)
                u[n, i] = uu(1.5, 2 + i * k);


            //формирование экземпляра класса SOrelax
            SORelax SOR = new SORelax(n, h, m, k, b, u);

            //пименение метода SOR
            int Imax = 0;
            int Jmax = 0;
            int counter = 0;
            double ereal = 0;
            counter = SOR.method(eps, out ereal, maxStep, Imax, Jmax);

            //оценка точности решения
            Imax = 1;
            Jmax = 1;
            for (int i = 1; i < 2 * n; i++)
            {
                for (int j = 1; j < m; j++)
                {
                    if (Math.Abs(uu(1 + i * h, 2 + j * k) - SOR.u[i, j]) > Math.Abs(uu(1 + Imax * h, 2 + Jmax * k) - SOR.u[Imax, Jmax]))
                    {
                        Imax = i;
                        Jmax = j;
                    }
                }
            }

            for (int i = 1; i < n; i++)
            {
                for (int j = m; j < 2 * m; j++)
                {
                    if (Math.Abs(uu(1 + i * h, 2 + j * k) - SOR.u[i, j]) > Math.Abs(uu(1 + Imax * h, 2 + Jmax * k) - SOR.u[Imax, Jmax]))
                    {
                        Imax = i;
                        Jmax = j;
                    }
                }
            }
            //

            textBox1.Text = SOR.w.ToString() + "   -параметр метода" 
                + Environment.NewLine + counter.ToString() + "   -число шагов"
                + Environment.NewLine + ereal.ToString() + "   -достигнутая точность метода"
                + Environment.NewLine + Math.Abs(uu(1 + Imax * h, 2 + Jmax * k) - SOR.u[Imax, Jmax]).ToString() + "    -погрешность решения";
        }
    }
}
